home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Linux / Kubuntu 8.10 / kubuntu-8.10-desktop-i386.iso / casper / filesystem.squashfs / usr / lib / python2.5 / idlelib / MultiCall.pyc (.txt) < prev    next >
Python Compiled Bytecode  |  2008-10-29  |  16KB  |  373 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.5)
  3.  
  4. '''
  5. MultiCall - a class which inherits its methods from a Tkinter widget (Text, for
  6. example), but enables multiple calls of functions per virtual event - all
  7. matching events will be called, not only the most specific one. This is done
  8. by wrapping the event functions - event_add, event_delete and event_info.
  9. MultiCall recognizes only a subset of legal event sequences. Sequences which
  10. are not recognized are treated by the original Tk handling mechanism. A
  11. more-specific event will be called before a less-specific event.
  12.  
  13. The recognized sequences are complete one-event sequences (no emacs-style
  14. Ctrl-X Ctrl-C, no shortcuts like <3>), for all types of events.
  15. Key/Button Press/Release events can have modifiers.
  16. The recognized modifiers are Shift, Control, Option and Command for Mac, and
  17. Control, Alt, Shift, Meta/M for other platforms.
  18.  
  19. For all events which were handled by MultiCall, a new member is added to the
  20. event instance passed to the binded functions - mc_type. This is one of the
  21. event type constants defined in this module (such as MC_KEYPRESS).
  22. For Key/Button events (which are handled by MultiCall and may receive
  23. modifiers), another member is added - mc_state. This member gives the state
  24. of the recognized modifiers, as a combination of the modifier constants
  25. also defined in this module (for example, MC_SHIFT).
  26. Using these members is absolutely portable.
  27.  
  28. The order by which events are called is defined by these rules:
  29. 1. A more-specific event will be called before a less-specific event.
  30. 2. A recently-binded event will be called before a previously-binded event,
  31.    unless this conflicts with the first rule.
  32. Each function will be called at most once for each event.
  33. '''
  34. import sys
  35. import os
  36. import string
  37. import re
  38. import Tkinter
  39. MC_KEYPRESS = 0
  40. MC_KEYRELEASE = 1
  41. MC_BUTTONPRESS = 2
  42. MC_BUTTONRELEASE = 3
  43. MC_ACTIVATE = 4
  44. MC_CIRCULATE = 5
  45. MC_COLORMAP = 6
  46. MC_CONFIGURE = 7
  47. MC_DEACTIVATE = 8
  48. MC_DESTROY = 9
  49. MC_ENTER = 10
  50. MC_EXPOSE = 11
  51. MC_FOCUSIN = 12
  52. MC_FOCUSOUT = 13
  53. MC_GRAVITY = 14
  54. MC_LEAVE = 15
  55. MC_MAP = 16
  56. MC_MOTION = 17
  57. MC_MOUSEWHEEL = 18
  58. MC_PROPERTY = 19
  59. MC_REPARENT = 20
  60. MC_UNMAP = 21
  61. MC_VISIBILITY = 22
  62. MC_SHIFT = 1
  63. MC_CONTROL = 4
  64. MC_ALT = 8
  65. MC_META = 32
  66. MC_OPTION = 64
  67. MC_COMMAND = 128
  68. if sys.platform == 'darwin' and sys.executable.count('.app'):
  69.     _modifiers = (('Shift',), ('Control',), ('Option',), ('Command',))
  70.     _modifier_masks = (MC_SHIFT, MC_CONTROL, MC_OPTION, MC_COMMAND)
  71. else:
  72.     _modifiers = (('Control',), ('Alt',), ('Shift',), ('Meta', 'M'))
  73.     _modifier_masks = (MC_CONTROL, MC_ALT, MC_SHIFT, MC_META)
  74. _modifier_names = []([ (name, number) for number in range(len(_modifiers)) for name in _modifiers[number] ])
  75.  
  76. class _SimpleBinder:
  77.     
  78.     def __init__(self, type, widget, widgetinst):
  79.         self.type = type
  80.         self.sequence = '<' + _types[type][0] + '>'
  81.         self.widget = widget
  82.         self.widgetinst = widgetinst
  83.         self.bindedfuncs = []
  84.         self.handlerid = None
  85.  
  86.     
  87.     def bind(self, triplet, func):
  88.         if not self.handlerid:
  89.             
  90.             def handler(event, l = self.bindedfuncs, mc_type = self.type):
  91.                 event.mc_type = mc_type
  92.                 wascalled = { }
  93.                 for i in range(len(l) - 1, -1, -1):
  94.                     func = l[i]
  95.                     if func not in wascalled:
  96.                         wascalled[func] = True
  97.                         r = func(event)
  98.                         if r:
  99.                             return r
  100.                         
  101.                     r
  102.                 
  103.  
  104.             self.handlerid = self.widget.bind(self.widgetinst, self.sequence, handler)
  105.         
  106.         self.bindedfuncs.append(func)
  107.  
  108.     
  109.     def unbind(self, triplet, func):
  110.         self.bindedfuncs.remove(func)
  111.         if not self.bindedfuncs:
  112.             self.widget.unbind(self.widgetinst, self.sequence, self.handlerid)
  113.             self.handlerid = None
  114.         
  115.  
  116.     
  117.     def __del__(self):
  118.         if self.handlerid:
  119.             self.widget.unbind(self.widgetinst, self.sequence, self.handlerid)
  120.         
  121.  
  122.  
  123. _states = range(1 << len(_modifiers))
  124. _state_names = [ []([], _[3], '') for s in _states ]
  125. _state_subsets = map((lambda i: (filter,)((lambda j: not (j & ~i)), _states)
  126. ), _states)
  127. for l in _state_subsets:
  128.     l.sort((lambda a, b, nummod = (lambda x: len((filter,)((lambda i: 1 << i & x), range(len(_modifiers))))
  129. ): nummod(b) - nummod(a)))
  130.  
  131. _state_codes = [ []([], _[5], 0) for s in _states ]
  132.  
  133. class _ComplexBinder:
  134.     
  135.     def _ComplexBinder__create_handler(self, lists, mc_type, mc_state):
  136.         
  137.         def handler(event, lists = lists, mc_type = mc_type, mc_state = mc_state, ishandlerrunning = self.ishandlerrunning, doafterhandler = self.doafterhandler):
  138.             ishandlerrunning[:] = [
  139.                 True]
  140.             event.mc_type = mc_type
  141.             event.mc_state = mc_state
  142.             wascalled = { }
  143.             r = None
  144.             for l in lists:
  145.                 for i in range(len(l) - 1, -1, -1):
  146.                     func = l[i]
  147.                     if func not in wascalled:
  148.                         wascalled[func] = True
  149.                         r = l[i](event)
  150.                         if r:
  151.                             break
  152.                         
  153.                     r
  154.                 
  155.                 if r:
  156.                     break
  157.                     continue
  158.             
  159.             ishandlerrunning[:] = []
  160.             while doafterhandler:
  161.                 doafterhandler.pop()()
  162.             if r:
  163.                 return r
  164.             
  165.  
  166.         return handler
  167.  
  168.     
  169.     def __init__(self, type, widget, widgetinst):
  170.         self.type = type
  171.         self.typename = _types[type][0]
  172.         self.widget = widget
  173.         self.widgetinst = widgetinst
  174.         [][None] = [ [] for s in _states ]
  175.         self.bindedfuncs = []
  176.         self.handlerids = []
  177.         self.ishandlerrunning = []
  178.         self.doafterhandler = []
  179.         for s in _states:
  180.             lists = [ self.bindedfuncs[None][i] for i in _state_subsets[s] ]
  181.             handler = self._ComplexBinder__create_handler(lists, type, _state_codes[s])
  182.             seq = '<' + _state_names[s] + self.typename + '>'
  183.             self.handlerids.append((seq, self.widget.bind(self.widgetinst, seq, handler)))
  184.         
  185.  
  186.     
  187.     def bind(self, triplet, func):
  188.         
  189.         doit = lambda : self.bindedfuncs[triplet[2]][triplet[0]].append(func)
  190.         if not self.ishandlerrunning:
  191.             doit()
  192.         else:
  193.             self.doafterhandler.append(doit)
  194.  
  195.     
  196.     def unbind(self, triplet, func):
  197.         
  198.         doit = lambda : self.bindedfuncs[triplet[2]][triplet[0]].remove(func)
  199.         if not self.ishandlerrunning:
  200.             doit()
  201.         else:
  202.             self.doafterhandler.append(doit)
  203.  
  204.     
  205.     def __del__(self):
  206.         for seq, id in self.handlerids:
  207.             self.widget.unbind(self.widgetinst, seq, id)
  208.         
  209.  
  210.  
  211. _types = (('KeyPress', 'Key'), ('KeyRelease',), ('ButtonPress', 'Button'), ('ButtonRelease',), ('Activate',), ('Circulate',), ('Colormap',), ('Configure',), ('Deactivate',), ('Destroy',), ('Enter',), ('Expose',), ('FocusIn',), ('FocusOut',), ('Gravity',), ('Leave',), ('Map',), ('Motion',), ('MouseWheel',), ('Property',), ('Reparent',), ('Unmap',), ('Visibility',))
  212. _binder_classes = (_ComplexBinder,) * 4 + (_SimpleBinder,) * (len(_types) - 4)
  213. _type_names = []([ (name, number) for number in range(len(_types)) for name in _types[number] ])
  214. _keysym_re = re.compile('^\\w+$')
  215. _button_re = re.compile('^[1-5]$')
  216.  
  217. def _parse_sequence(sequence):
  218.     '''Get a string which should describe an event sequence. If it is
  219.     successfully parsed as one, return a tuple containing the state (as an int),
  220.     the event type (as an index of _types), and the detail - None if none, or a
  221.     string if there is one. If the parsing is unsuccessful, return None.
  222.     '''
  223.     if not sequence and sequence[0] != '<' or sequence[-1] != '>':
  224.         return None
  225.     
  226.     words = string.split(sequence[1:-1], '-')
  227.     modifiers = 0
  228.     while words and words[0] in _modifier_names:
  229.         modifiers |= 1 << _modifier_names[words[0]]
  230.         del words[0]
  231.     if words and words[0] in _type_names:
  232.         type = _type_names[words[0]]
  233.         del words[0]
  234.     else:
  235.         return None
  236.     if _binder_classes[type] is _SimpleBinder:
  237.         if modifiers or words:
  238.             return None
  239.         else:
  240.             detail = None
  241.     elif [] in [ _type_names[s] for s in ('KeyPress', 'KeyRelease') ]:
  242.         type_re = _keysym_re
  243.     else:
  244.         type_re = _button_re
  245.     if not words:
  246.         detail = None
  247.     elif len(words) == 1 and type_re.match(words[0]):
  248.         detail = words[0]
  249.     else:
  250.         return None
  251.     return (modifiers, type, detail)
  252.  
  253.  
  254. def _triplet_to_sequence(triplet):
  255.     if triplet[2]:
  256.         return '<' + _state_names[triplet[0]] + _types[triplet[1]][0] + '-' + triplet[2] + '>'
  257.     else:
  258.         return '<' + _state_names[triplet[0]] + _types[triplet[1]][0] + '>'
  259.  
  260. _multicall_dict = { }
  261.  
  262. def MultiCallCreator(widget):
  263.     '''Return a MultiCall class which inherits its methods from the
  264.     given widget class (for example, Tkinter.Text). This is used
  265.     instead of a templating mechanism.
  266.     '''
  267.     if widget in _multicall_dict:
  268.         return _multicall_dict[widget]
  269.     
  270.     
  271.     class MultiCall((widget,)):
  272.         if not issubclass(widget, Tkinter.Misc):
  273.             raise AssertionError
  274.         
  275.         def __init__(self, *args, **kwargs):
  276.             apply(widget.__init__, (self,) + args, kwargs)
  277.             self._MultiCall__eventinfo = { }
  278.             self._MultiCall__binders = [ _binder_classes[i](i, widget, self) for i in range(len(_types)) ]
  279.  
  280.         
  281.         def bind(self, sequence = None, func = None, add = (None,)):
  282.             if type(sequence) is str and len(sequence) > 2 and sequence[:2] == '<<' and sequence[-2:] == '>>':
  283.                 if sequence in self._MultiCall__eventinfo:
  284.                     ei = self._MultiCall__eventinfo[sequence]
  285.                     if ei[0] is not None:
  286.                         for triplet in ei[1]:
  287.                             self._MultiCall__binders[triplet[1]].unbind(triplet, ei[0])
  288.                         
  289.                     
  290.                     ei[0] = func
  291.                     if ei[0] is not None:
  292.                         for triplet in ei[1]:
  293.                             self._MultiCall__binders[triplet[1]].bind(triplet, func)
  294.                         
  295.                     
  296.                 else:
  297.                     self._MultiCall__eventinfo[sequence] = [
  298.                         func,
  299.                         []]
  300.             
  301.             return widget.bind(self, sequence, func, add)
  302.  
  303.         
  304.         def unbind(self, sequence, funcid = (None,)):
  305.             if type(sequence) is str and len(sequence) > 2 and sequence[:2] == '<<' and sequence[-2:] == '>>' and sequence in self._MultiCall__eventinfo:
  306.                 (func, triplets) = self._MultiCall__eventinfo[sequence]
  307.                 if func is not None:
  308.                     for triplet in triplets:
  309.                         self._MultiCall__binders[triplet[1]].unbind(triplet, func)
  310.                     
  311.                     self._MultiCall__eventinfo[sequence][0] = None
  312.                 
  313.             
  314.             return widget.unbind(self, sequence, funcid)
  315.  
  316.         
  317.         def event_add(self, virtual, *sequences):
  318.             if virtual not in self._MultiCall__eventinfo:
  319.                 self._MultiCall__eventinfo[virtual] = [
  320.                     None,
  321.                     []]
  322.             
  323.             (func, triplets) = self._MultiCall__eventinfo[virtual]
  324.             for seq in sequences:
  325.                 triplet = _parse_sequence(seq)
  326.                 if triplet is None:
  327.                     widget.event_add(self, virtual, seq)
  328.                     continue
  329.                 if func is not None:
  330.                     self._MultiCall__binders[triplet[1]].bind(triplet, func)
  331.                 
  332.                 triplets.append(triplet)
  333.             
  334.  
  335.         
  336.         def event_delete(self, virtual, *sequences):
  337.             if virtual not in self._MultiCall__eventinfo:
  338.                 return None
  339.             
  340.             (func, triplets) = self._MultiCall__eventinfo[virtual]
  341.             for seq in sequences:
  342.                 triplet = _parse_sequence(seq)
  343.                 if triplet is None:
  344.                     widget.event_delete(self, virtual, seq)
  345.                     continue
  346.                 if func is not None:
  347.                     self._MultiCall__binders[triplet[1]].unbind(triplet, func)
  348.                 
  349.                 triplets.remove(triplet)
  350.             
  351.  
  352.         
  353.         def event_info(self, virtual = (None,)):
  354.             if virtual is None or virtual not in self._MultiCall__eventinfo:
  355.                 return widget.event_info(self, virtual)
  356.             else:
  357.                 return tuple(map(_triplet_to_sequence, self._MultiCall__eventinfo[virtual][1])) + widget.event_info(self, virtual)
  358.  
  359.         
  360.         def __del__(self):
  361.             for virtual in self._MultiCall__eventinfo:
  362.                 (func, triplets) = self._MultiCall__eventinfo[virtual]
  363.                 if func:
  364.                     for triplet in triplets:
  365.                         self._MultiCall__binders[triplet[1]].unbind(triplet, func)
  366.                     
  367.             
  368.  
  369.  
  370.     _multicall_dict[widget] = MultiCall
  371.     return MultiCall
  372.  
  373.